﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Web.Configuration;
using System.Data.Common;
using System.Data;
using System.Diagnostics;
using System.Data.Linq.Mapping;
using GcTicket.Model;

namespace GcTicket.BLL.Data
{
    /// <summary>
    /// 实体类数据库操作
    /// </summary>
    /// <typeparam name="Entity">实体类</typeparam>
    //[DebuggerStepThrough]
    public sealed class EntityManager<Entity>:DataContext 
        where Entity:EntityBase,new()
    {
        private readonly string connectionString;
        private bool _useTransaction = false;
        private bool _disposed = false;
        private DbTransaction _t = null;

        public EntityManager(string connectionString)
            : base(connectionString)
        {
            if (String.IsNullOrEmpty(connectionString))
                throw new ArgumentNullException();

            this.connectionString = connectionString;
        }

        public EntityManager()//无参构造函数
            : this(DbConnectionString.SQLConnectionString)
        {
            ;
        }

        [Obsolete]
        public EntityManager(bool useTransaction)
            : this()
        {
            this._useTransaction = useTransaction;
            
        }
        private void init()
        {
            if (_useTransaction)
                _t = this.Connection.BeginTransaction(IsolationLevel.Serializable);
        }
        public void Commit()
        {
            if (_disposed)
                throw new ObjectDisposedException(this.ToString());

            if (_useTransaction)
            {
                _t.Commit();
                _t = null;
            }
            this.Dispose();
        }

        public void Rollback()
        {
            if (_disposed)
                throw new ObjectDisposedException(this.ToString());

            if (_useTransaction)
            {
                _t.Rollback();
                _t = null;
            }
            this.Dispose();
        }

        public new void Dispose()
        {
            base.Dispose();
            if (!_disposed)
            {
                if (this.Connection != null)
                {
                    if (_t != null)
                    {
                        _t.Rollback();
                        _t = null;
                    }

                    this.Connection.Close();
                }
                _disposed = true;
                GC.SuppressFinalize(this);
            }
        }

        public Table<Entity> Entities
        {
            get
            {
                Table<Entity> entities = this.GetTable<Entity>();
#if DEBUG
                this.Log = Console.Out;
#endif
                return entities;
            }
        }

        /// <summary>
        /// 获取实体类信息
        /// </summary>
        /// <param name="id">PKID</param>
        /// <returns>实体类</returns>
        public Entity EntityGet(int id)
        {
            Entity entity = new Entity();
            var results = from a in this.Entities where a.Id == id select a;
            Debug.Write(this.Log);
#if DEBUG
            this.Log = Console.Out;
#endif
            return results.First();
        }

        /// <summary>
        /// 执行Insert操作
        /// </summary>
        /// <param name="entity">实体类</param>
        public void EntityCreate(Entity entity)
        {
            this.Entities.InsertOnSubmit(entity);
            this.SubmitChanges();
        }

        public void EntityCreate(IEnumerable<Entity> entities)
        {
            this.Entities.InsertAllOnSubmit(entities);
            this.SubmitChanges();
        }

        public void EntityUpdate(Entity entity)
        {
            this.Entities.Attach(entity);
            /*
             * RefreshMode.OverwriteCurrentValues => 使用当前数据库中的值，覆盖Linq缓存中实体对象的值
             * RefreshMode.KeepCurrentValues =>使用Linq缓存中实体对象的值，覆盖当前数据库中的值
             * RefreshMode.KeepChanges=>只更新实体对象中改变的字段的值，其他的保留不变             
             */
            this.Refresh(RefreshMode.KeepCurrentValues, entity);
            this.SubmitChanges();
        }

        public void EntityUpdate(IEnumerable<Entity> entities)
        {
            this.Entities.AttachAll(entities);
            this.Refresh(RefreshMode.OverwriteCurrentValues, entities);
            this.SubmitChanges();
        }

        public void EntityDelete(Entity entity)
        {
            this.Entities.DeleteOnSubmit(entity);
            this.SubmitChanges();
        }

        public void EntityDelete(IEnumerable<Entity> entities)
        {
            this.Entities.DeleteAllOnSubmit(entities);
            this.SubmitChanges();
        }

        public void EntityDelete(int id)
        {
            Entity entity = this.EntityGet(id);
            this.EntityDelete(entity);
        }

        /// <summary>
        /// 执行特定SQL操作
        /// </summary>
        /// <param name="sql">SQL语句</param>
        /// <param name="objs">参数</param>
        /// <returns>执行结果</returns>
        public new int ExecuteCommand(string sql, params object[] objs)
        {
            return base.ExecuteCommand(sql, objs);
        }

        /// <summary>
        /// 执行特定SQL操作
        /// </summary>
        /// <param name="sql">SQL语句</param>
        /// <param name="objs">参数</param>
        /// <returns>集合</returns>
        public IEnumerable<Entity> ExecuteQuery(string sql, params object[] objs)
        {
            return base.ExecuteQuery<Entity>(sql, objs);
        }
    }
}
